package org.jflame.context.filemanager;

import org.jflame.commons.config.ConfigHolder;
import org.jflame.commons.config.ConfigReader;
import org.jflame.commons.util.StringHelper;
import org.jflame.context.filemanager.FastDFSFileManager.FastDFSCfg;
import org.jflame.context.filemanager.FtpFileManager.FtpCfg;
import org.jflame.context.filemanager.MinioFileManager.MinioCfg;


public abstract class FileManagerFactory {

    private static volatile IFileManager instance;

    /**
     * 从配置项构造一个文件管理类IFileManager实例.
     * <p>
     * 配置项与配置类属性对应,示例:
     *
     * <pre>
     * jflame.file.client-type=minio
     * jflame.file.server=
     * jflame.file.save-path=
     * jflame.file.minio.endpoint=
     * jflame.file.minio.access-id=
     * jflame.file.minio.access-secret=
     * jflame.file.minio.bucket=
     * jflame.file.minio.region=
     * jflame.file.minio.connection-timeout=
     * </pre>
     *
     * @param fileManageConfig 配置
     * @return IFileManager IFileManager实现类
     */
    public static IFileManager build(ConfigReader fileManageConfig) {
        String typeName = fileManageConfig.getString(FileManagerCfg.JFLAME_FILE_CFG_TYPE);
        if (StringHelper.isEmpty(typeName)) {
            throw new RuntimeException("IFileManager instantiation exception, please configure: " + FileManagerCfg.JFLAME_FILE_CFG_TYPE);
        }
        String server = fileManageConfig.getString(FileManagerCfg.JFLAME_FILE_CFG_PREFIX + ".server");
        String savePath = fileManageConfig.getString(FileManagerCfg.JFLAME_FILE_CFG_PREFIX + ".save-path", "");
        FileManagerType type = FileManagerType.valueOf(typeName.toLowerCase());
        String propPrefix = FileManagerCfg.JFLAME_FILE_CFG_PREFIX + "." + type.name();
        switch (type) {
            case local:
                return new LocalFileManager(new FileManagerCfg(savePath, server));
            case fastdfs:
                FastDFSCfg cfg = new FastDFSCfg(savePath, server);
                fileManageConfig.bindBean(cfg, propPrefix);
                return new FastDFSFileManager(cfg);
            case alioss:
                OssManagerCfg acfg = new OssManagerCfg();
                acfg.setServer(server);
                acfg.setSavePath(savePath);
                fileManageConfig.bindBean(acfg, propPrefix);
                return new AliOssFileManager(acfg);
            case cos:
                OssManagerCfg ccfg = new OssManagerCfg();
                ccfg.setServer(server);
                ccfg.setSavePath(savePath);
                fileManageConfig.bindBean(ccfg, propPrefix);
                return new TencentCosFileManager(ccfg);
            case minio:
                MinioCfg mcfg = new MinioCfg();
                mcfg.setServer(server);
                mcfg.setSavePath(savePath);
                fileManageConfig.bindBean(mcfg, propPrefix);
                return new MinioFileManager(mcfg);
            case ftp:
                FtpCfg fcfg = new FtpCfg();
                fcfg.setServer(server);
                fcfg.setSavePath(savePath);
                fileManageConfig.bindBean(fcfg, propPrefix);
                return new FtpFileManager(fcfg);
            default:
                throw new IllegalStateException("Unsupported file manager type");
        }

    }

    /**
     * 返回当前生效的文件管理类,如果不存在自动根据默认配置文件实例化一个
     *
     * @return IFileManager
     */
    public static IFileManager getCurrentManager() {
        if (instance == null) {
            synchronized (FileManagerFactory.class) {
                if (instance == null) {
                    if (ConfigHolder.getConfig() != null) {
                        instance = build(ConfigHolder.getConfig());
                    }
                }
            }
        }

        return instance;
    }
}
